package algoritmos;

import java.util.ArrayList;
import java.util.List;

import options.XQueryOptions;

import mapeamento.MapeamentoAbsoluto;
import mapeamento.MapeamentoRelativo;
import parsedquery.Conceito;


public class JoinSplitFragments {
	
	public static List<String> execute(List<Conceito> query, List<MapeamentoAbsoluto> mapAbsoluto, List<MapeamentoRelativo> mapRelativo) {

		Conceito prevCon = query.get(0);
		List<String> cWhere = new ArrayList<String>();
		String IDREF = "";
		String idrefConcept = "";
		String idrefConceptOid = "";
		List<String> idrefSources = null;
		String idConcept = "";
		String idConceptOid = "";
		List<String> idSources = null;
		
		for (int i = 0; i < query.size(); i++) {
			Conceito con = query.get(i);
			StringBuffer expressaoLeft = new StringBuffer();
			StringBuffer expressaoRight = new StringBuffer();
			String baseUri = new String();

			if (!con.getLcm().equals(prevCon.getLcm())){
				if (getIdRef(prevCon.getConceito(), con.getConceito(), mapAbsoluto, mapRelativo) == null){
					IDREF = getIdRef(con.getConceito(), prevCon.getConceito(), mapAbsoluto, mapRelativo);
					idrefConcept = con.getConceito();
					idrefConceptOid = con.getOid();
					idrefSources = con.getFontes();
					idConcept = prevCon.getConceito();
					idConceptOid = prevCon.getOid();
					idSources = prevCon.getFontes();
				}
				else{
					IDREF = getIdRef(prevCon.getConceito(), con.getConceito(), mapAbsoluto, mapRelativo);
					idrefConcept = prevCon.getConceito();
					idrefConceptOid = prevCon.getOid();
					idrefSources = prevCon.getFontes();
					idConcept = con.getConceito();
					idConceptOid = con.getOid();
					idSources = con.getFontes();					
				}
				
				for (int j = 0; j < idrefSources.size(); j++) {
					String caminho = procuraCaminhoRelativo(idrefConcept, IDREF, idrefSources.get(j), mapRelativo);
					if ((idrefSources.size() > 1) && (XQueryOptions.SHOW_BASE_URI)) {
						baseUri = "[base-uri(.)=\"" + idrefSources.get(j) + "\"]";
					}
					if (j > 0) {
						expressaoLeft.append(" | ");
					}
					expressaoLeft.append("$v" + idrefConceptOid + baseUri + "/" + caminho);
				}
				
				baseUri = new String();
				
				for (int k = 0; k < idSources.size(); k++) {
					String caminho = procuraCaminhoRelativo(idConcept, IDREF, idSources.get(k), mapRelativo);
					if ((idSources.size() > 1) && (XQueryOptions.SHOW_BASE_URI)) {
						baseUri = "[base-uri(.)=\"" + idSources.get(k) + "\"]"; 
					}
					if (k > 0) {
						expressaoRight.append(" | ");
					}
					expressaoRight.append("$v" + idConceptOid + baseUri + "/" + caminho);
				}
				
				cWhere.add("(" + expressaoLeft.toString() + ") = (" + expressaoRight.toString() + ")");				
			}
			
			prevCon = query.get(i);
		}
		
		return cWhere;
	}
	
	public static String getIdRef(String con1, String con2, List<MapeamentoAbsoluto> mapAbsoluto, List<MapeamentoRelativo> mapRelativo) {
		String ref = null;

		for (int i = 0; i < mapAbsoluto.size(); i++) {
			MapeamentoAbsoluto map = mapAbsoluto.get(i);
			if (map.getConceito().equals(con2)) {
				ref = map.getChave();
			}
		}

		return ref;
	}
	
	private static String procuraCaminhoRelativo(String prevConceito, String conceito, String fonte, List<MapeamentoRelativo> mapRelativo) {
		String caminho = null;
		
		for (int i = 0; i < mapRelativo.size(); i++) {
			MapeamentoRelativo map = mapRelativo.get(i);
			if (map.getOrigem().equals(prevConceito) && map.getDestino().equals(conceito)
				&& map.getUrl().equals(fonte)) {
				caminho = map.getExpressao();
			}
		}

		return caminho;
	}
}
